package cn.com.manager.controller;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;

import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.impl.persistence.entity.ProcessDefinitionEntity;
import org.activiti.engine.impl.pvm.process.ActivityImpl;
import org.activiti.engine.repository.DeploymentBuilder;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.repository.ProcessDefinitionQuery;
import org.activiti.engine.runtime.ProcessInstance;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import cn.com.manager.page.PageInfo;
import cn.com.manager.pojo.JsonResult;

@Controller
@RequestMapping("/workflow")
public class WorkFlowController {
	private static final Logger logger = LoggerFactory.getLogger(WorkFlowController.class);
	@Autowired
	private RepositoryService repositoryService;
	@Autowired
	private RuntimeService runtimeService;

	/**
	 * 跳转流程部署页面
	 * @return
     */
	@RequestMapping("/flowDefinitionPage")
	public String flowDefinitionPage() {
		return "workflow/flowDefinitionPage";
	}

	/**
	 * 开始部署流程
	 * @param title
	 * @param bpmnFile
	 * @param pngFile
	 * @param model
     * @return
     */
	@RequestMapping("/deployFlow")
	public String deployFlow(@RequestParam(value = "title", required = false) String title,
			@RequestParam(value = "bpmnFile", required = true) MultipartFile bpmnFile,
			@RequestParam(value = "pngFile", required = true) MultipartFile pngFile,Model model) {
		boolean flag = true;
		try {
			DeploymentBuilder builder = repositoryService.createDeployment().addInputStream(bpmnFile.getOriginalFilename(), bpmnFile.getInputStream()).addInputStream(pngFile.getOriginalFilename(), pngFile.getInputStream());
			if(StringUtils.isNotBlank(title)){
				builder.name(title);
			}
			builder.deploy();
		} catch (IOException e) {
			logger.error("流程部署失败，{}",e);
			flag = false;
		}
		if(!flag){
			model.addAttribute("message","流程部署失败");
		}else{
			model.addAttribute("message","流程部署成功");
		}
		return "workflow/flowDefinitionPage";
	}

	/**
	 * 查询流程定义信息
	 * @param processDefinitionId
	 * @param pageInfo
	 * @param model
     * @return
     */
	@RequestMapping("/queryProcessDefinition")
	public String queryProcessDefinition(@RequestParam(value="processDefinitionId",required=false)String processDefinitionId,PageInfo pageInfo,Model model){
		ProcessDefinitionQuery processDefinitionQuery = repositoryService.createProcessDefinitionQuery();
		if(StringUtils.isNoneBlank(processDefinitionId)){
			processDefinitionQuery.processDefinitionId(processDefinitionId);
		}
		processDefinitionQuery.orderByProcessDefinitionVersion().desc();
		pageInfo.setCount(processDefinitionQuery.list().size());
		List<ProcessDefinition> list = new ArrayList<>();
		if(pageInfo.getCount()!=0){			
			list = processDefinitionQuery.listPage(pageInfo.getOffset(), pageInfo.getOffset()+pageInfo.getPageSize());
		}
		model.addAttribute("definitionList",list);
		return "workflow/queryProcessDefinition";
	}

	/**
	 * 查询流程资源文件
	 * @param response
	 * @param processDefinitionId
	 * @param resourceType
     */
	@RequestMapping("/queryProcessDefinitionResource")
	public void queryProcessDefinitionResource(HttpServletResponse response, @RequestParam(value="processDefinitionId",required=true)String processDefinitionId, @RequestParam(value="resourceType",required=true)String resourceType){
		ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionId(processDefinitionId).singleResult();
		InputStream resourceAsStream = null;
		if (StringUtils.equals("bpmnResource",resourceType)){
			resourceAsStream = repositoryService.getResourceAsStream(processDefinition.getDeploymentId(),processDefinition.getResourceName());
		}else if(StringUtils.equals("pngResource",resourceType)){
			resourceAsStream = repositoryService.getResourceAsStream(processDefinition.getDeploymentId(), processDefinition.getDiagramResourceName());
		}
		try {
			ServletOutputStream outputStream = response.getOutputStream();
			IOUtils.copy(resourceAsStream,outputStream);
		} catch (IOException e) {
			logger.error("查看流程文件错误,{}",e);
		}
	}
	
	/**
	 * 删除流程定义
	 * @param processDefinitionId
	 * @return
	 */
	@RequestMapping("/deleteProcessDefinition")
	@ResponseBody
	public JsonResult deleteProcessDefinition(@RequestParam(value="processDefinitionId",required=true)String processDefinitionId){
		ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionId(processDefinitionId).singleResult();
		repositoryService.deleteDeployment(processDefinition.getDeploymentId(),true);
		JsonResult jsonResult = new JsonResult();
		jsonResult.setCode(0);
		jsonResult.setMessage("删除成功");
		return jsonResult;
	}
	
	@RequestMapping("/queryActivityMap")
	public String queryActivityMap(@RequestParam(value="instanceId",required=false)String instanceId,Model model){
		ProcessInstance instance = runtimeService.createProcessInstanceQuery().processInstanceId(instanceId).singleResult();
		ProcessDefinitionEntity processDefinitionEntity = (ProcessDefinitionEntity)repositoryService.getProcessDefinition(instance.getProcessDefinitionId());
		ActivityImpl activity = processDefinitionEntity.findActivity(instance.getActivityId());
		int activity_x = activity.getX();
		int activity_y = activity.getY();
		int activity_width = activity.getWidth();
		int activity_height = activity.getHeight();
		
		model.addAttribute("activity_x",activity_x);
		model.addAttribute("activity_y",activity_y);
		model.addAttribute("activity_width",activity_width);
		model.addAttribute("activity_height",activity_height);
		model.addAttribute("processDefinitionId",instance.getProcessDefinitionId());
		
		return "workflow/queryActivityMap";
	}
}
